<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
    <style>
        .active{color:red}
    </style>
</head>
<body>
  

    
    <p>文字</p>
    <p>文字2</p>
    <div>good</div>
    
<script>

// 面试为何会考察原理,又用不到?
// 之前然知其所以然一各行业通 用的道理
// 了解原理,才能应用的更好(竞争激烈,择优录取)
// 大厂造轮子(有钱有资源,业务定制,技术KPI)

// 面试如何考察Vue原理?
// 考察重点,而不是考察细节。掌握好2/8原则
// 和使用相关联的原理,例如vdom、模板渲染
// 整体流程是否全面?热[门技术是否有深度?


// Vue原理
// ◆组件化
// ◆模板编译
// ◆响应式
// ◆渲染过程
// ◆vdom 和diff
// ◆前端路由


// 再次回顾之前的Vue面试题
// ◆Vue 组件如何通讯
// ◆描述组件渲染和更新的过程
// ◆双向数据绑定v-model的实现原理


// 数据驱动视图
// ◆传统组件,只是静态渲染,更新还要依赖于操作DOM
// ◆数据驱动视图- Vue MVVM
// ◆数据驱动视图- React setState (暂时按下不表)


// Vue响应式
// ◆组件data的数据一旦变化,立刻触发视图的更新
// ◆实现数据驱动视图的第一步
// ◆考察Vue原理的第一题


// Vue响应式
// ◆核心API - Object.defineProperty
// ◆如何实现响应式,代码演示
// ◆Object.defineProperty 的一些缺点( Vue3.0启用Proxy )


// Proxy有兼容性问题
// ◆Proxy 兼容性不好,且无法polyfill
// ◆Vue2.x 还会存在一-段时间 ,所以都得学
// ◆Vue3.0 相关知识，下一章讲,这里只是先提一下

// Object.defineProperty缺点
// 深度监听,需要递归到底, -次性计算量大
// 无法监听新增属性/删除属性( Vue.set Vue.delete )
 

// 虚拟DOM(vdom)和diff
// ◆DOM操作非常耗费性能
// ◆以前用jQuery ,可以自行控制DOM操作的时机,手动调整
// ◆Vue和React是数据驱动视图,如何有效控制DOM操作?


// 解决方案- vdom
// 有了一定复杂度,想减少计算次数比较难
// 能不能把计算,更多的转移为JS计算?因为JS执行速度很快
// vdom-用JS模拟DOM结构,计算出最小的变更,操作DOM


// 通过snabbdom学习vd om
// 简洁强大的vdom库,易学易用
// Vue参考它实现的vdom和diff
// https://github.com/snabbdom/snabbdom


// 通过snabbdom学习vdom
// Vue3.0重写了vdom的代码,优化了性能;
// 但vdom的基本理念不变,面试考点也不变
// React vdom具体实现和Vue也不同,但不妨碍统一学习


// diff算法
// ◆diff 算法是vdom中最核心、最关键的部分
// ◆diff 算法能在日常使用vue React中体现出来(如key )
// ◆diff 算法是前端热[ ]话题,面试“宠儿"


// diff算法概述
// ◆diff即对比，是- -个广泛的概念,如linux diff命令、git diff等
// 两个js对象也可以做diff , 如https://github.com/cujojs/jiff
// 两棵树做diff , 如这里的vdom diff


// 模板编译
// 模板是vue开发中最常用的部分,即与使用相关联的原理
// 它不是htm| ,有指令、插值、JS表达式,到底是什么?
// 面试不会直接问,但会通过“组件渲染和更新过程”考察


// 模板编译
// ◆前置知识: JS的with语法
// ◆vue template complier将模板编译为render函数
// ◆执行render函数生成vnode


var obj = {a:100,b:200};
with(obj){
    console.log(a);
    console.log(b);
    // console.log(a);
}
//使用with能改变{}内自由变量的查找方式
//将{}内自由变量，当做obj的属性来查找
// 会破坏作用域规则，易读性变差


// 编译模板
// ◆
// 模板不是html ,有指令、插值、JS表达式,能实现判断、循环
// ◆html是标签语言,只有JS才能实现判断、循环(图灵完备的)
// ◆因此,模板-定是转换为某种JS代码,即编译模板

// vue-template-compiler

const compiler = require('vue-template-compiler');
const template = `<p>{{msg}}</p>`

// 编译
const res = compiler.compile(template);
console.log(res.render);
//  width(this){return _c("p",[_v(_s(msg))])}
// createElement  _v createTextNode   toString

// 编译模板
// LDFDDD168
// ◆模板编译为render函数,执行render函数返回vnode
// ◆基于vnode再执行patch和diff (后面会讲)

// vue 组件可以使用render 代替 template


// 初次渲染过程
// ◆解析模板为render函数(或在开发环境已完成，vue-loader )
// ◆触发响应式,监听data属性getter setter
// ◆执行render函数,生成vnode ，patch(elem, vnode)

// 更新过程

// 修改data , 触发setter ( 此前在getter中已被监听)
// 重新执行render函数,生成newVnode
// patch(vnode, newVnode)


// 异步渲染
// ◆回顾$nextTick
// ◆汇总data的修改, - -次性更新视图
// ◆减少DOM操作次数,提高性能


// 总结1
// ◆渲染和响应式的关系
// ◆渲染和模板编译的关系
// ◆渲染和vdom的关系


// 总结2
// ◆初次渲染过程
// ◆更新过程
// ◆异步渲染


// 前端路由原理
// ◆稍微复杂一点的SPA ,都需要路由
// ◆vue-router 也是vue全家桶的标配之一
// ◆属于“和日常使用相关联的原理” ,面试常考


// 网页url组成部分
// // http:// 127.0.0.1: 8881/01-hash. html?a=100&b=20#/ aaa/ bbb 
// location. protocol // 'http:
// location. hostname // '127.0.0.1'
// location.host // ' 127.0.0.1:8881 '
// location.port // ' 8881 '
// locat ion . pathname // ' /01-Fash. html '
// location. search // ' ?a=100&b=20 '
// location.hash // ' #/aaa/bbb '


// LDFDDD168
// ◆hash 变化会触发网页跳转,即浏览器的前进、后退
// ◆hash 变化不会刷新页面, SPA必需的特点
// ◆hash 永远不会提交到server端(前端自生自灭)

window.onhashchange = e=>{
    console.log(oldURL,e.newUrl);
    console.log('hash',location.hash)
}
document.addEventListener('DOMContentLoaded',()=>{
    console.log("hash:",location.hash);
})

document.getElementById("btn1").addEventListener("click",location.href='#/user')


// H5 history
// ◆用url规范的路由,但跳转时不刷新页面
// ◆history.pushState
// ◆window.onpopstate


// 正常页面浏览
// ◆https://github.com/xxx 刷新页面
// ◆https://github.com/xxx/yyy 刷新页面
 
// ◆https://github.com/xxx/yyy/zzz 刷新页面


// 正常页面浏览
// ◆https://github.com/xxx 刷新页面
// ◆https://github.com/xxx/yyy 刷新页面
 
// ◆https://github.com/xxx/yyy/zzz 刷新页面

btn.addEventListener("click",()=>{
    const state  = {name:"page1"}
    console.log("切换路由到","page1");
    history.pushState(state,'','page1');
})

window.onpopstate = event=>{
    console.log('onpopstate',event.state,location.pathname)
}

// 两者选择
// ◆toB的系统推荐用hash,简单易用,对url规范不敏感
// ◆to C的系统,可以考虑选择H5 history , 但需要服务端支持

// v-show和v-if的区别
// v-show通过CSS display控制显示和隐藏
// v-if组件真正的渲染和销毁,而不是显示和隐藏
// 频繁切换显示状态用v-show , 否则用v-if


// 为何在v-for中用key
// 必须用key，且不能是index和random
// diff算法中通过tag和key来判断,是否是sameNode
// 减少渲染次数,提升渲染性能


 
// 描述Vue组件生命周期(父 子组件)
// ◆单组件生命周期图
// ◆父子组件生命周期关系


// Vue组件如何通讯(常见)
// ◆父子组件props和this. $emit
// ◆自定义事件event.$no event. $off event.$emit
// ◆vuex


// 描述组件更新渲染过程

// data数据改变，watch监听  触发render函数  虚拟dom

 
// 双向数据绑定v-model的实现原理
// ◆input 元素的value = this.name
// ◆绑定input事件this.name = $event.target.value
// ◆data 更新触发re-render
/*
mvvm

view     viewModel                     model
dom      DOM Listener  | Directive    plain  javascript object 
         view
*/

// computed有何特点
// ◆缓存，data不变不会重新计算
// ◆提高性能

// 为何组件data必须是-一个函数?
// 实例化多个组件  各组件会相互影响

// 如何将组件所有props传递给子组件?
// ◆$props .
// ◆<User v-bind=“$props" />


// 如何自己实现v-model

// <template>
// <input
// type="text"
// :value="text"
// @input=" $emit('change', $event,target.value )"
// <!--
// 注意
// 第一，上面使用:value 而没用v-model
// 第二，上面的change 和model. event对应起来即可，名字自己改
// - ->
// </ template>
// <script>
// export default {
// model: {
// prop: 'text', //对应到props text 
// event: ' change "
// }，
// props: {
// teyt: String 
// }


// 多个组件有相同的逻辑,如何抽离?
// mixin
// 以及mixin的一些缺点

// 何时要使用异步组件?
// imooc
// ◆加载大组件
// ◆
// 路由异步加载

// 何时需要使用keep-alive ?
// ◆缓存组件,不需要重复渲染
// ◆如多个静态tab页的切换
// ◆优化性能

// 何时需要使用beforeDestory
// ◆解绑自定义事件event. $off
// ◆清除定时器
// ◆解绑自定义的DOM事件,如window scroll等


// 什么是作用域插槽

// Vuex中action和mutation有何区别
// ◆action 中处理异步, mutation不可以
// ◆mutation 做原子操作
// ◆action 可以整合多个mutation

// Vue-router常用的路由模式
// hash默认
// imooc
// H5 history (需要服务端支持)
// 两者比较

// 如何配置Vue-router异步加载

componet:()=>import(
    /* webpackChunkName:'about' */
    '../components/about'
)

// 请用vnode描述- -个DOM结构


// 监听data变化的核心API是什么
 
// ◆Object.defineProperty
// ◆以及深度监听、监听数组
// ◆有何缺点


// Vue如何监听数组变化
// ◆Object.defineProperty不能监听数组变化
// ◆重新定义原型,重写push pop等方法,实现监听
// ◆Proxy可以原生支持监听数组变化


// 请描述响应式原理
// ◆监听data.变化
// ◆组件渲染和更新的流程


// diff算法的时间复杂度
// ◆O(n)
// ◆在O(n^3) 基础.上做了- -些调整

// Vue为何是异步渲染, $nextTick 何用?
// ◆异步渲染(以及合并data修改) , 以提高渲染性能
// ◆$nextTick 在DOM更新完之后,触发回调

// Vue常见性能优化方式
// ◆合理使用v-show和v-if
// ◆合理使用computed
// ◆v-for 时加key ,以及避免和v-if同时使用


// Vue常见性能优化方式
// ◆自定义事件、DOM事件及时销毁
// ◆合理使用异步组件。
// ◆合理使用keep-alive

// Vue常见性能优化方式
// ◆data 层级不要太深
// ◆使用vue-loader在开发环境做模板编译(预编译)
// ◆合理使用keep-alive


// Vue常见性能优化方式
// ◆webpack 层面的优化(后面会讲)
// ◆前端通用的性能优化,如图片懒加载
// ◆使用SSR




</script>
</body>
</html>

 
